home *** CD-ROM | disk | FTP | other *** search
/ One Click 14 / OneClick14.iso / Ferramentas / Convert XLS to Pdf / xls2pdf_setup.exe / {app} / lib / pdf_ops.ps < prev    next >
Encoding:
Text File  |  2002-10-11  |  17.8 KB  |  589 lines

  1. %    Copyright (C) 1994, 2000 Aladdin Enterprises.  All rights reserved.
  2. % This software is provided AS-IS with no warranty, either express or
  3. % implied.
  4. % This software is distributed under license and may not be copied,
  5. % modified or distributed except as expressly authorized under the terms
  6. % of the license contained in the file LICENSE in this distribution.
  7. % For more information about licensing, please refer to
  8. % http://www.ghostscript.com/licensing/. For information on
  9. % commercial licensing, go to http://www.artifex.com/licensing/ or
  10. % contact Artifex Software, Inc., 101 Lucas Valley Road #110,
  11. % San Rafael, CA  94903, U.S.A., +1(415)492-9861.
  12.  
  13. % $Id: pdf_ops.ps,v 1.26 2002/10/10 18:17:59 igor Exp $
  14. % Definitions for most of the PDF operators.
  15.  
  16. .currentglobal true .setglobal
  17.  
  18. % Define pdfmark.  Don't allow it to be bound in.
  19. % Also don't define it in systemdict, because this leads some Adobe code
  20. % to think this interpreter is a distiller.
  21. % (If this interpreter really is a distiller, don't do this.)
  22. systemdict /pdfmark known not
  23.  { userdict /pdfmark { cleartomark } bind put } if
  24.  
  25. userdict /GS_PDF_ProcSet 127 dict dup begin
  26.  
  27. % ---------------- Abbreviations ---------------- %
  28.  
  29. /bdef { bind def } bind def
  30.  
  31. % ---------------- Graphics state stack ---------------- %
  32.  
  33. % PDF adds a number of parameters to the graphics state.
  34. % We implement this by pushing and popping a dictionary
  35. % each time we do a PDF gsave or grestore.
  36. % The keys in this dictionary are as follows:
  37. %    self            % identifies the dictionary as one of ours
  38. %    ClipRect        % (optional)
  39. %    Show
  40. %    TextSaveMatrix        % matrix at time of BT (iff within BT/ET)
  41. % (The following correspond directly to PDF state parameters.)
  42. %    AlphaIsShape
  43. %    FillConstantAlpha
  44. %    FillColor
  45. %    FillColorSpace
  46. %    FillOverprint
  47. %    SoftMask
  48. %    StrokeConstantAlpha
  49. %    StrokeColor
  50. %    StrokeColorSpace
  51. %    StrokeOverprint
  52. %    TextSpacing
  53. %    TextHScaling
  54. %    Leading
  55. %    TextFont
  56. %    TextLineMatrix
  57. %    TextMatrix
  58. %    TextRise
  59. %    TextRenderingMode
  60. %    WordSpacing
  61.  
  62. /nodict 1 dict def
  63. nodict /self { //nodict } executeonly put
  64. nodict readonly pop
  65.  
  66. /dictbeginpage {    % <initialdict> dictbeginpage -
  67.   //nodict 20 dict .copydict begin { def } forall
  68.   graphicsbeginpage textbeginpage
  69. } bdef
  70. /endpage {    % - endpage -
  71.   showpage end
  72. } bdef
  73.  
  74. /graphicsbeginpage {
  75.   initgraphics
  76.   currentdict /ClipRect knownoget { aload pop rectclip } if
  77.   0 g  0 G  false op  false OP  0 OPM
  78.   1 ca  1 CA  null SMask  false AIS  /Compatible BM  true TK
  79. } bdef
  80.  
  81. /gput        % <value> <key> gput -
  82.  { exch currentdict //nodict eq { /self dup load end 5 dict begin def } if
  83.         % If we're in a Level 1 system, we need to grow the
  84.         % dictionary explicitly.
  85.    currentdict length currentdict maxlength ge %eq
  86.     { currentdict dup length 3 mul 2 idiv 1 add dict .copydict end begin 
  87.     }
  88.    if def
  89.  } bdef
  90.  
  91. /q {
  92.   gsave //nodict begin
  93. } bdef
  94. % Some PDF files have excess Q operators!
  95. /Q {
  96.   currentdict /self .knownget {
  97.     exec //nodict eq { end grestore false } { true } ifelse
  98.   } {
  99.     true    % formaterror -- not a gsave dict
  100.   } ifelse
  101.   { (\n   **** File has imbalanced q/Q operators \(too many Q's\) ****\n)
  102.     pdfformaterror
  103.   } if
  104. } bdef
  105.  
  106. % ---------------- Color setting ---------------- %
  107.  
  108. /fcput        % <color> <colorspace> fcput -
  109.  { /FillColorSpace gput /FillColor gput
  110.  } bdef
  111. /scput        % <color> <colorspace> scput -
  112.  { /StrokeColorSpace gput /StrokeColor gput
  113.  } bdef
  114.  
  115. /csdevgray [/DeviceGray] readonly def
  116. /csdevrgb [/DeviceRGB] readonly def
  117. /csdevcmyk [/DeviceCMYK] readonly def
  118. /cspattern [/Pattern] readonly def
  119. /nullpattern1 mark
  120.    /PatternType 1 /PaintType 1 /TilingType 3 /BBox [0 0 0 0]
  121.    /XStep 1 /YStep 1 /PaintProc { }
  122. .dicttomark readonly def
  123. /nullpattern2 nullpattern1 dup length dict copy readonly def
  124.  
  125. % Each entry in the color space dictionary is a procedure of the form
  126. %    <cspace> -proc- <cspace> <initial-color>
  127. /CSdict mark
  128.   /DeviceGray { pop //csdevgray 0 } bind
  129.   /DeviceRGB { pop //csdevrgb [0 0 0] cvx } bind
  130.   /DeviceCMYK { pop //csdevcmyk [0 0 0 1] cvx } bind
  131.   /CIEBasedA { 0 } bind
  132.   /CIEBasedABC { [0 0 0] cvx } bind
  133.   /ICCBased { [ 1 index 1 oget /N get { 0 } repeat ] cvx } bind
  134.   /Separation { 1 } bind
  135.   /DeviceN {    % What is the correct value??
  136.     [ 1 index 1 get length { 1 } repeat ] cvx
  137.   } bind
  138.   /Indexed { 0 } bind
  139.   /Pattern {
  140.     dup type /nametype eq 1 index length 1 eq or {
  141.       pop //cspattern //nullpattern1 matrix makepattern
  142.     } {
  143.       //nullpattern2 matrix makepattern 1 index 1 get csset
  144.         % Stack: patternspace nullpattern basecolor basespace
  145.       pop [ 3 1 roll dup type /arraytype eq { aload pop } if
  146.       counttomark -1 roll ] cvx
  147.     } ifelse
  148.   } bind
  149. .dicttomark readonly def
  150. /csset            % <cspace> csset <color> <cspace>
  151.  { dup dup type /nametype ne { 0 get } if //CSdict exch get exec exch
  152.  } bdef
  153.  
  154. /g { //csdevgray fcput } bdef
  155. /G { //csdevgray scput } bdef
  156. /rg { 3 array astore cvx //csdevrgb fcput } bdef
  157. /RG { 3 array astore cvx //csdevrgb scput } bdef
  158. /k { 4 array astore cvx //csdevcmyk fcput } bdef
  159. /K { 4 array astore cvx //csdevcmyk scput } bdef
  160. /cs { csset fcput } bdef
  161. /CS { csset scput } bdef
  162. /ri { pop } bdef
  163. % We have to break up sc according to the number of operands.
  164. /sc1 { /FillColor gput } bdef
  165. /SC1 { /StrokeColor gput } bdef
  166. % We have to avoid storing into a color array associated with an outer
  167. % gsave level, so we do a kind of "copy on write".
  168. /sc* {
  169.   currentdict /FillColor .knownget {
  170.     astore pop
  171.   } {
  172.     /FillColor load length array astore cvx /FillColor gput
  173.   } ifelse
  174. } bdef
  175. /SC* {
  176.   currentdict /StrokeColor .knownget {
  177.     astore pop
  178.   } {
  179.     /StrokeColor load length array astore cvx /StrokeColor gput
  180.   } ifelse
  181. } bdef
  182.  
  183. % ---------------- Overprint/transparency setting ---------------- %
  184.  
  185. /op { /FillOverprint gput } bdef
  186. /OP { /StrokeOverprint gput } bdef
  187. /OPM {
  188.   /.setoverprintmode where { pop .setoverprintmode } { pop } ifelse
  189. } bdef
  190. /ca { /FillConstantAlpha gput } bdef
  191. /CA { /StrokeConstantAlpha gput } bdef
  192. /SMask { /SoftMask gput } bdef
  193. /AIS { /AlphaIsShape gput } bdef
  194. /BM {
  195.   /.setblendmode where {
  196.     pop [ exch dup type /nametype ne { aload pop } if /Normal ] {
  197.       { .setblendmode } .internalstopped not { exit } if pop
  198.     } forall
  199.   } {
  200.     pop
  201.   } ifelse
  202. } bdef
  203. /TK {
  204.   /.settextknockout where { pop .settextknockout } { pop } ifelse
  205. } bdef
  206.  
  207. % ---------------- Color installation ---------------- %
  208.  
  209. % Establish a given color (and color space) as current.
  210. /.settransparencyparams {    % <alpha> <smask> .settransparencyparams -
  211.   /.begintransparencymask where {
  212.     pop AlphaIsShape {
  213.       1 .setopacityalpha 0 .inittransparencymask exch .setshapealpha 1
  214.     } {
  215.       1 .setshapealpha 1 .inittransparencymask exch .setopacityalpha 0
  216.     } ifelse
  217.     % Set the soft mask by rendering the XObject.  Doing this every time
  218.     % is obviously very inefficient; we'll improve it later.
  219.     .settransparencymask    
  220.   } {
  221.     pop pop
  222.   } ifelse
  223. } bdef
  224. /.settransparencymask {        % <paramdict> <masknum> .settransparencymask -
  225.   exch dup null eq {
  226.     pop .inittransparencymask
  227.   } {
  228.     dup /Draw get exec
  229.   } ifelse
  230. } bdef
  231. % (Non-mask) images must execute setfillblend.
  232. /setfillblend {
  233.   FillOverprint setoverprint
  234.   FillConstantAlpha SoftMask .settransparencyparams
  235. } def
  236. /setfillstate {
  237.   FillColor FillColorSpace setgcolor setfillblend
  238. } def
  239. /setstrokestate {
  240.   StrokeColor StrokeColorSpace setgcolor StrokeOverprint setoverprint
  241.   StrokeConstantAlpha SoftMask .settransparencyparams
  242. } def
  243. /Cdict 15 dict dup begin    % <color...> <colorspace> -proc- -
  244.   /DeviceGray { pop setgray } bdef
  245.   /DeviceRGB { pop setrgbcolor } bdef
  246.   /DeviceCMYK { pop setcmykcolor } bdef
  247.   /CIEBasedA { setgcolorspace setcolor } bdef
  248.   /CIEBasedABC /CIEBasedA load def
  249.   /CIEBasedDEF /CIEBasedA load def
  250.   /CIEBasedDEFG /CIEBasedA load def
  251.   /ICCBased /CIEBasedA load def
  252.   /Separation /CIEBasedA load def
  253.   /DeviceN /CIEBasedA load def
  254.   /Indexed /CIEBasedA load def
  255.   /Pattern
  256.    { setgcolorspace
  257.  
  258.      % Since multiple patterns may share
  259.      % same data stream, we need to ensure
  260.      % that the stream is at 0 position.
  261.      % Making this consistently with resolveshading,
  262.      % which applies ReusableStreamDecode filter
  263.      % to the PS stream, which represents the
  264.      % PDF stream in dynamics.
  265.  
  266.      dup /Shading knownoget {
  267.        dup /ShadingType oget 4 ge {
  268.          /DataSource knownoget {
  269.            dup type /filetype eq {
  270.              0 setfileposition
  271.            } {
  272.              pop
  273.            } ifelse
  274.          } if
  275.        } {
  276.         pop
  277.        } ifelse
  278.      } if
  279.  
  280.      dup /Matrix knownoget not { matrix } if
  281.      gsave DefaultMatrix setmatrix makepattern grestore setcolor
  282.    } bdef
  283. end def
  284. /setgcolor    % (null | <color...>) <colorspace> setgcolor -
  285.  { 1 index null eq
  286.     { pop pop }
  287.     { dup 0 get //Cdict exch get exec }
  288.    ifelse
  289.  } bdef
  290. % Compare the old and new color spaces in an attempt to avoid expensive
  291. % reloads of CIEBased color spaces.
  292. /PCSdict 15 dict dup begin    % <colorspace> -proc- <colorspace|pdfcspace>
  293.   /CIEBasedA { dup 1 get /PDFColorSpace .knownget { exch pop } if } bdef
  294.   /CIEBasedABC /CIEBasedA load def
  295.   /CIEBasedDEF /CIEBasedA load def
  296.   /CIEBasedDEFG /CIEBasedA load def
  297.   /Indexed {
  298.     dup 1 get dup pdfcolorspace 2 copy ne { 3 1 roll } if pop pop
  299.   } bdef
  300. end def
  301. /pdfcolorspace {    % <colorspace> pdfcolorspace <colorspace|pdfcspace>
  302.   dup type /arraytype eq {
  303.     //PCSdict 1 index 0 get .knownget { exec } if
  304.   } if
  305. } bdef
  306. /setgcolorspace {    % <colorspace> setgcolorspace -
  307.   dup pdfcolorspace currentcolorspace pdfcolorspace eq {
  308.     pop
  309.   } {
  310.     setcolorspace
  311.   } ifelse
  312. } bdef
  313. /fsexec        % <fillop|strokeop> fsexec -
  314.  {        % Preserve the current point, if any.
  315.     { currentpoint } stopped
  316.     { $error /newerror false put   cvx exec }
  317.     { 3 -1 roll cvx exec moveto }
  318.    ifelse
  319.  } bdef
  320.  
  321. % ---------------- Path painting and clipping ---------------- %
  322.  
  323. /S { setstrokestate /stroke fsexec } bdef
  324. /f { setfillstate /fill fsexec } bdef
  325. /f* { setfillstate /eofill fsexec } bdef
  326. /n { newpath } bdef        % don't allow n to get bound in
  327. /s { closepath S } bdef
  328. /B { gsave setfillstate fill grestore S } bdef
  329. /b { closepath B } bdef
  330. /B* { gsave setfillstate eofill grestore S } bdef
  331. /b* { closepath B* } bdef
  332.  
  333. % Clipping:
  334.  
  335. /Wdict 4 dict dup begin
  336. /S { gsave setstrokestate stroke grestore n } bdef
  337. /f { gsave setfillstate fill grestore n } bdef
  338. /f* { gsave setfillstate eofill grestore n } bdef
  339. /n { end clip newpath } bdef
  340. end readonly def
  341. /W { //Wdict begin } bdef
  342. /W*dict 4 dict dup begin
  343. Wdict { def } forall
  344. /n { end eoclip newpath } bdef
  345. end readonly def
  346. /W* { //W*dict begin } bdef
  347.  
  348. % ---------------- Text control ---------------- %
  349.  
  350. /textbeginpage
  351.  { /TextSpacing 0 def        % 0 Tc
  352.    /TextLeading 0 def        % 0 TL
  353.    /TextRenderingMode 0 def    % 0 Tr
  354.    /TextRise 0 def        % 0 Ts
  355.    /WordSpacing 0 def        % 0 Tw
  356.    /TextHScaling 1.0 def    % 100 Tz
  357.    /TextFont null def
  358.    /Show { showfirst } def
  359.  } bdef
  360.  
  361. % Contrary to the statement in the PDF manual, BT and ET *can* be nested,
  362. % if the CharProc for a Type 3 font does a BT/ET itself.
  363. % Since we always call the CharProc inside a q/Q, we simply ensure that
  364. % the text state is saved and restored like the rest of the extended
  365. % graphics state.
  366.  
  367. /settextmatrix {
  368.   TextMatrix concat
  369.   TextHScaling 1 ne { TextHScaling 1 scale } if
  370.   TextRise 0 ne { 0 TextRise translate } if
  371.   TextFont dup null eq { pop } { setfont } ifelse
  372. } bdef
  373. /settextstate {
  374.     % The text state can be set even outside BT/ET.
  375.   currentdict /TextSaveMatrix known {
  376.     TextSaveMatrix setmatrix settextmatrix
  377.   } if
  378. } bdef
  379. /settextposition {
  380.         % Update the TextMatrix translation.
  381.   gsave TextSaveMatrix setmatrix
  382.   currentpoint TextMatrix 4 2 getinterval astore pop
  383.         % We would like to do "grestore currentpoint translate"
  384.         % here, but some PDF files set a singular text matrix
  385.         % (0 0 0 0 <x> <y> Tm), so we can't do this.
  386.   TextTempMatrix identmatrix setmatrix currentpoint
  387.   grestore
  388.   TextTempMatrix currentmatrix 4 2 getinterval astore pop
  389.   TextTempMatrix setmatrix
  390. } bdef
  391.  
  392. /BT {
  393.   currentdict /TextLineMatrix .knownget
  394.     { identmatrix pop TextMatrix identmatrix pop }
  395.     { matrix /TextLineMatrix gput matrix /TextMatrix gput }
  396.   ifelse
  397.   { showfirst } /Show gput
  398.   currentdict /TextSaveMatrix .knownget not {
  399.     matrix dup /TextSaveMatrix gput
  400.   } if currentmatrix pop settextmatrix
  401.   matrix /TextTempMatrix gput        % see settextposition
  402. } bdef
  403. /ET {
  404.   TextRenderingMode 4 ge { clip newpath } if
  405.   TextSaveMatrix setmatrix
  406.   currentdict /TextSaveMatrix undef
  407. } bdef
  408. /Tc { /TextSpacing gput { showfirst } /Show gput } bdef
  409. /TL { /TextLeading gput } bdef
  410. /Tr { /TextRenderingMode gput { showfirst } /Show gput } bdef
  411. /Ts { /TextRise gput settextstate } bdef
  412. /Tw { /WordSpacing gput { showfirst } /Show gput } bdef
  413. /Tz { 100 div /TextHScaling gput settextstate} bdef
  414.  
  415. % ---------------- Font control ---------------- %
  416.  
  417. /Tf {        % <font> <scale> Tf -
  418.   dup 1 eq { pop } { scalefont } ifelse
  419.   /TextFont gput settextstate
  420. } bdef
  421.  
  422. % Read a CFF font.
  423. /FRD        % <resname> <file> FRD -
  424.  { /FontSetInit /ProcSet findresource begin true ReadData
  425.  } bdef
  426.  
  427. % Copy a font, removing its FID.  If changed is true, also remove
  428. % the UniqueID and XUID, if any.  If the original dictionary doesn't have
  429. % the keys being removed, don't copy it.
  430. /.copyfontdict        % <font> <changed> .copyfontdict <dict>
  431.  { 1 index /FID known
  432.    1 index { 2 index /UniqueID known or 2 index /XUID known or } if
  433.     {        % We add 1 to the length just in case the original
  434.         % didn't have a FID.
  435.       exch dup length 1 add dict exch
  436.        {        % Stack: changed newfont key value
  437.      1 index /FID eq 4 index
  438.       { 2 index /UniqueID eq or 2 index /XUID eq or }
  439.      if not { 3 copy put } if pop pop
  440.        }
  441.       forall exch
  442.     }
  443.    if pop
  444.  } bdef
  445.  
  446. % Insert a new Encoding or Metrics into a font if necessary.
  447. % Return a possibly updated font, and a flag to indicate whether
  448. % the font was actually copied.
  449. /.updatefontmetrics {    % <font> <Metrics|null> .updatefontmetrics
  450.             %   <font'> <copied>
  451.   dup null ne {
  452.     exch true .copyfontdict dup /Metrics 4 -1 roll put true
  453.   } {
  454.     pop false
  455.   } ifelse
  456. } bdef
  457. /.updatefontencoding {    % <font> <Encoding|null> .updatefontencoding
  458.             %   <font'> <copied>
  459.   dup null ne { dup 2 index /Encoding get ne } { false } ifelse {
  460.     exch false .copyfontdict dup /Encoding 4 -1 roll put true
  461.   } {
  462.     pop false
  463.   } ifelse
  464. } bdef
  465. /.updatefont {        % <font> <Encoding|null> <Metrics|null> .updatefont
  466.             %   <font'> <copied>
  467.   3 -1 roll exch .updatefontmetrics
  468.             % Stack: enc|null font' copied
  469.   3 1 roll exch .updatefontencoding 3 -1 roll or
  470. } bdef
  471.  
  472. % ---------------- Text positioning ---------------- %
  473.  
  474. /Td {
  475.   TextLineMatrix transform TextLineMatrix 4 2 getinterval astore pop
  476.   TextLineMatrix TextMatrix copy pop settextstate
  477. } bdef
  478. /TD { dup neg /TextLeading gput Td } bdef
  479. /T* { 0 TextLeading neg Td } bdef
  480. /Tm {
  481.   TextLineMatrix astore TextMatrix copy pop settextstate
  482. } bdef
  483.  
  484. % ---------------- Text painting ---------------- %
  485.  
  486. /Vexch {
  487.   rootfont /WMode knownoget { 1 eq { exch } if } if
  488. } bind def
  489.  
  490. /textrenderingprocs [        % (0 is handled specially)
  491.     % Painting-only modes
  492.    { tf } { tS } { tB } { tn }
  493.     % Clipping modes
  494.    { gsave tf grestore tW }
  495.    { gsave tS grestore tW }
  496.    { gsave tB grestore tW }
  497.    { tW }
  498. ] readonly def
  499. /setshowstate
  500.  { WordSpacing 0 eq TextSpacing 0 eq and
  501.     { TextRenderingMode 0 eq {
  502.         { setfillstate show }
  503.       } {
  504.         TextRenderingMode 3 eq {
  505.           {     % Some PDF files execute 'tm' with a singular matrix,
  506.         % and then use this text rendering mode.
  507.         % The graphics library currently cannot handle text
  508.         % operations when the CTM is singular.
  509.         % Work around this here.
  510.         matrix currentmatrix
  511.         {1 0 0 1 0 0} setmatrix
  512.         exch stringwidth
  513.         3 -1 roll setmatrix
  514.         rmoveto
  515.  
  516.           }
  517.         } {
  518.           { false charpath textrenderingprocs TextRenderingMode get exec }
  519.         } ifelse
  520.       } ifelse
  521.     }
  522.     { TextRenderingMode 0 eq
  523.        { WordSpacing 0 eq
  524.           { { setfillstate TextSpacing 0 Vexch 3 -1 roll ashow } }
  525.       { TextSpacing 0 eq
  526.             { { setfillstate WordSpacing 0 Vexch 32 4 -1 roll widthshow } }
  527.             { { setfillstate WordSpacing 0 Vexch 32
  528.                  TextSpacing 0 Vexch 6 -1 roll awidthshow } }
  529.         ifelse
  530.       }
  531.      ifelse
  532.        }
  533.        { { WordSpacing TextSpacing
  534.             % Implement the combination of t3 and false charpath.
  535.             % Note that we must use cshow for this, because we
  536.             % can't parse multi-byte strings any other way.
  537.             % Stack: string xword xchar
  538.         { pop pop (x) dup 0 3 index put false charpath
  539.             % Stack: xword xchar ccode
  540.              3 copy 32 eq { add } { exch pop } ifelse 0 Vexch rmoveto pop
  541.         }
  542.        4 -1 roll cshow pop pop
  543.        textrenderingprocs TextRenderingMode get exec
  544.      }
  545.        }
  546.       ifelse
  547.     }
  548.    ifelse /Show gput
  549.  } bdef
  550. /showfirst { setshowstate Show } def
  551.  
  552. /Tj {
  553.   0 0 moveto Show settextposition
  554. } bdef
  555. /' { T* Tj } bdef
  556. /" { exch Tc exch Tw T* Tj } bdef
  557. /TJ {
  558.   0 0 moveto {
  559.     dup type /stringtype eq {
  560.       Show
  561.     } { -1000 div
  562.       currentfont /ScaleMatrix .knownget { 0 get mul } if
  563.       0 Vexch rmoveto
  564.     } ifelse
  565.   } forall settextposition
  566. } bdef
  567.  
  568. /tf { setfillstate currentpoint fill moveto } bdef
  569. /tn { currentpoint newpath moveto } bdef
  570. % For stroking characters, temporarily restore the graphics CTM so that
  571. % the line width will be transformed properly.
  572. /Tmatrix matrix def
  573. /tS
  574.  { setstrokestate
  575.    currentpoint //Tmatrix currentmatrix TextSaveMatrix setmatrix stroke
  576.    setmatrix moveto
  577.  } bdef
  578. /tB { gsave tf grestore tS } bdef
  579. % This does the wrong thing if there have been multiple text operations
  580. % within a single BT/ET pair, but it's a start.
  581. /tW { } bdef
  582.  
  583. end readonly put        % GS_PDF_ProcSet
  584.  
  585. .setglobal
  586.